﻿using System;
using System.Collections.Generic;

namespace Allegro.Mathlib
{
    public class NormalDistribution : IProbabilityDistribution
    {
        private double _mean;
        private double _std;
        private static double _sqrt2 = Math.Sqrt(2.0);
        private static double _sqrt2pi = Math.Sqrt(2.0 * Math.PI);
        private double _var;
        private double _factor;

        public NormalDistribution(double mean, double stdev)
        {
            _mean = mean;
            _std = stdev;
            _var = _std * _std;
            _factor = 1.0 / (_std * _sqrt2pi);
        }
        public double Mean
        {
            get { return _mean; }
        }
        public double StdDev
        {
            get { return _std; }
        }
        public double Density(double x)
        {
            double dx = x - _mean;
            double d = _factor* Math.Exp(-dx * dx / (2.0 * _var));
            return d;
        }

        public double Probability(double x)
        {
            double p = 0.5 * (1.0 + Statistics.Erf((x - _mean) / (_sqrt2 * _std)));
            return p;
        }

        public double Inverse(double p)
        {
            double x = _mean + _std * _sqrt2 * Statistics.InvErf(2.0 * p - 1.0);
            return x;
        }

        public double FromStandardValue(double x)
        {
            return _std*x + _mean;
        }

        public double ToStandardValue(double x)
        {
            return (x - _mean)/_std;
        }
    }
}
